home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
pd
/
serien
/
purity
/
nr.12
/
workshop
/
pascalkursiii.txt
< prev
next >
Wrap
Text File
|
1995-04-21
|
10KB
|
283 lines
========================================================================
= Systemprogrammierung in PCQ-Pascal =
= Kurs für AmigaGadget/Purity - Teil III =
========================================================================
Bisherige Kursteile :
Teil I : Voraussetzungen,Screens,Windows
Teil II : Einfache Grafikausgabe
Was für ein Tag ! Stoltenberg ist zurückgetreten und ich muß jetzt
noch schnell Teil drei dieses Kurses fertigstellen.... Schwitz.
Also gut, wie versprochen : noch einige Grafikbefehle :
im Include-File "Graphics/Text.i" finden sich unter anderem :
GText (window^.RPort,string,count) - Gibt einen Text, der in der
Variable string gespeichert ist
count Zeichen lang aus.
Normalerweise setzt man count:=
StrLen (string);
TextLength (window^.RPort,string,count) - Gibt die Anzahl der Pixel an,
die von count Zeichen des
Strings string benötigt
werden würden. Normalerweise
Zeichen*8, aber seit Kick2.0
sollte man da vorsichtig sein...
In den Includes "Graphics/Pens.i" und "Graphics/RastPort.i" erschließt
sich uns eine neue Dimension der Grafikausgabe :
gefüllte Flächen. Damit man diese darstellen kann, muß man vorerst
eine sogenannte TmpRas-Struktur einrichten und dem Rastport
einverleiben. Dies geschieht mit :
InitTmpRas (TmpRasPtr , Buffer , Buffersize) - Initialisiert eine solche
Struktur. Wie sieht das
Teil nun aus ?
TmpRas = record
RasPtr : Address;
Size : Integer;
end;
Yo, was wollen uns diese Variablen sagen ? Nun, RasPtr wird von
InitTmpRas besetzt und Size können wird mit der im File
"Graphics/Gfx.i" besetzt. Also : Size:=RASSIZE (Breite,Hoehe);
Buffer ist ein Zeiger auf ein vorher zu belegendes Raster.
Dieses wird mit Buffer:=AllocRaster (Breite,Hoehe) belegt.
Buffersize letztendlich kann wieder mit RASSIZE berechnet werden :
Buffersize:=RASSIZE (Breite,Hoehe).
Normalerweise verwendet man für Breite und Hoehe die entsprechenden
Ausmaße des Fensters.
Das ganze wird dann in die Windowstruktur eingebunden :
window^.RPort^.TmpRas:=TmpRasPtr;
Flood (window^.RPort,mode,x,y) - füllt eine zusammenhänge Fläche, in der
der Punkt P (x/y) enthalten ist. Mode
wird in der Regel 1 sein, Mode 0 benötigt
eine Umrandungslinie mit dem AOlPen und
ist an sich unnötig....
Es gibt noch einige andere Flächenformen, die zwar einfacher zu hand-
haben sind, die aber noch einiges weiteres an Strukturkram benötigen.
Deshalb : heute nicht ! Ein anderes Mal mehr dazu.
Nun wollen wir uns zwei Procedure schreiben, die uns die Arbeit verkürzen.
Nämlich in etwa so :
PROCEDURE Print (rp : Address; xs , ys : Short; stext : String);
BEGIN
Move (rp,xs,ys);
GText (rp,stext,StrLen(stext));
END;
und
PROCEDURE InitialisiereRaster (itmpras : TmpRasPtr; VAR ARaster : Address;
width , height : Short ; swindow : WindowPtr);
BEGIN
ARaster:=AllocRaster(width,height);
WITH itmpras^ DO
BEGIN
RasPtr := NIL;
Size := RASSIZE (width,height);
END;
InitTmpRas (itmpras , ARaster , RASSIZE (width,height));
swindow^.RPort^.TmpRas := itmpras;
END;
Und nicht vergessen : Wenn man das Programm beendet, dann sollte man
das belegte Raster mit FreeRaster (Buffer,Breite,Hoehe); wieder
freigeben.
Machen wir halt mal ein kloines Beispiel :
Program KursProgramm;
{ Listing für den AMIGAGadget/Purity - Pascalkurs , }
{ Dritte Schritte in der Grafikprogrammierung }
{$I "Include:Intuition/Intuition.I" }
{$I "Include:Exec/Libraries.I" }
{$I "Include:Graphics/Graphics.I" }
{$I "Include:Libraries/Dos.I" }
{$I "Include:Graphics/Pens.I" }
{$I "Include:Graphics/Rastport.I" }
{$I "Include:Utils/Stringlib.I" }
VAR
myscreen : ScreenPtr;
mywindow : WindowPtr;
PROCEDURE Line (rp : Address ; xs , ys , xe , ye : Short);
BEGIN
Move (rp , xs , ys); Draw (rp , xe , ye);
END;
PROCEDURE Box (rp : Address ; xs , ys , xe , ye : Short);
BEGIN
Line (rp,xs,ys,xe,ys); Line (rp,xe,ys,xe,ye);
Line (rp,xe,ye,xs,ye); Line (rp,xs,ye,xs,ys);
END;
PROCEDURE Print (rp : Address; xs , ys : Short; stext : String);
BEGIN
Move (rp,xs,ys);
GText (rp,stext,StrLen(stext));
END;
PROCEDURE InitialisiereRaster (itmpras : TmpRasPtr;
VAR ARaster : Address;
width , height : Short ;
swindow : WindowPtr);
BEGIN
ARaster:=AllocRaster(width,height);
WITH itmpras^ DO
BEGIN
RasPtr := NIL;
Size := RASSIZE (width,height);
END;
InitTmpRas (itmpras , ARaster , RASSIZE (width,height));
swindow^.RPort^.TmpRas := itmpras;
END;
PROCEDURE CloseDisplay;
VAR i : Integer;
{ Sollte ein Teil des Displays offen sein, dann wird er von }
{ dieser Routine geschlossen. }
BEGIN
IF mywindow<>NIL THEN
CloseWindow (mywindow);
IF myscreen<>NIL THEN
CloseScreen (myscreen);
IF GfxBase<>NIL THEN
CloseLibrary (GfxBase);
END;
PROCEDURE BreakProgram (reason : STRING);
{ Diese Routine schließt alles bisher geöffnete, druckt den }
{ Fehlergrund aus und bricht dann das Programm ab. }
BEGIN
CloseDisplay;
WRITELN ('Program error : ',reason);
Exit (42);
END;
PROCEDURE OpenLibs;
CONST GraphicName : String = "graphics.library";
BEGIN
GfxBase:=OpenLibrary (GraphicName,0);
END;
PROCEDURE OpenDisplay;
{ Diese Routine erstellt ein Display. }
CONST
mynewscreen : NewScreen = (0,0,640,256,2,0,1,HIRES,
CUSTOMSCREEN_f,NIL,
NIL,NIL,NIL);
NewWin : NewWindow = (100,50,320,128,0,1,0,
SMART_REFRESH+WINDOWDRAG+
ACTIVATE+SMART_REFRESH,NIL,NIL,
"Unsere neuen schicken Befehle !",
NIL,NIL,0,0,0,0,CUSTOMSCREEN_f);
BEGIN
myscreen := OpenScreen (Adr(mynewscreen));
IF myscreen=NIL THEN BreakProgram ("Couldn't open Screen");
NewWin.Screen:=myscreen;
mywindow := OpenWindow (Adr(NewWin));
IF mywindow=NIL THEN BreakProgram ("Couldn't open Window");
END;
PROCEDURE NeueBefehle;
{Demonstration der neuen Befehle. }
VAR MyTmpRas : TmpRas;
MyRaster : Address;
BEGIN
{Ganz am Anfang eine kleine Textausgabe }
SetAPen (mywindow^.RPort,1);
Print (mywindow^.RPort,10,20,"Hello World ! Let's have some");
Print (mywindow^.RPort,10,28,"NEW GRAPHIC FUNCTIONS !!!");
{Zuersteinmal Initialisierung der benötigten Strukturen. }
InitialisiereRaster (Adr(MyTmpRas),MyRaster,mywindow^.Width,
mywindow^.Height,mywindow);
{Und dann einen Kreis, der von uns gefüllt wird ! }
DrawCircle (mywindow^.RPort,60,70,20);
Flood (mywindow^.RPort,1,60,70);
{Auch noch ein gefülltes Dreieck.... }
Line (mywindow^.RPort,110,60,180,85);
Line (mywindow^.RPort,180,85,100,70);
Line (mywindow^.RPort,100,70,110,60);
Flood (mywindow^.RPort,1,120,65);
{Und wieder ein wenig Text }
SetAPen (mywindow^.RPort,3);
Print (mywindow^.RPort,10,110,"Das war's. See U later.");
FreeRaster (MyRaster,mywindow^.Width,mywindow^.Height);
END;
PROCEDURE WarteEinWenig;
BEGIN
Delay (1000);
END;
BEGIN
OpenLibs;
OpenDisplay;
NeueBefehle;
WarteEinWenig;
CloseDisplay;
END.
Es gäbe noch sehr viel über Grafik und ihre Anwendung zu erzählen, doch
finde ich es wichtiger, die Brücke zum Anwender zu schlagen, will
sagen, im nächsten Teil mit dem Kapitel Messages zu beginnen.
(Klingt geheimnisvoll, oder ?)
Wer Kritik oder Lob für diesen Kurs, Verbesserungsvorschläge oder
Fragen (es gibt keine dummen Fragen !!) hat, melde sich entweder bei mir
Andreas Neumann ; Auf dem Ruhbühl 151 ; 7997 Immenstaad
oder in der Purity. Bye.
© 1992 by Andreas Neumann für AmigaGadget von Nils Kassube
und Purity von Steppenbrand und Diesel